/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#include <lib3d/hard/Hardware.h>
#include <xml/Stream.h>
#include <Converter.h>
#include <safe_new.h>

#include "ModelFixed.h"

namespace liba
{
namespace lib3d
{
namespace node
{

const Atom ModelFixed::node_name("ModelFixed");
const Atom ModelFixed::source_name("Source");
const Atom ModelFixed::shadow_source_name("ShadowSource");

ModelFixed::ModelFixed( const Atom & name, Node * parent )
	: Model(name, parent)
{
	node_type = node_name;
	this->shadowSource.Changed().connect(boost::bind(&ModelFixed::ShadowSourceChanged, this, _1));
	this->RegisterProperty(shadow_source_name, &this->shadowSource);
}

ModelFixed::ModelFixed(const ModelFixed& rhs)
	: Model(rhs)
	, shadowSource(rhs.shadowSource)
{
	this->shadowSource.Changed().connect(boost::bind(&ModelFixed::ShadowSourceChanged, this, _1));
	this->RegisterProperty(shadow_source_name, &this->shadowSource);
}

ModelFixed::~ModelFixed()
{}

ModelFixed * ModelFixed::Clone()
{
	return new ModelFixed(*this);
}

bool ModelFixed::on_attribute( xml::Provider * prov, const std::string & name, const std::string & value )
{
	if ( name == "Source" )
	{
		normal_model.load_rep( value.c_str() );
		return true;
	}
#ifndef IPHONE_VERSION
	if ( name == "Shadow" )
	{
		shadow_model.load_rep( value.c_str() );
		return true;
	}
#endif
	return Model::on_attribute( prov, name, value );
}

/*bool ModelFixed::render( hard::Hardware * hardware, const CameraDesc & camera_desc )
{
	bool result = get_rep()->render( get_shaders(), hardware, camera_desc ); // BUG result is unused
	return Model::render( hardware, camera_desc );
}*/

void ModelFixed::RenderToList( hard::Hardware * hardware, hard::RenderList * render_list )
{
	hard::RenderModel model_ref;
	model_ref.world = GetGlobalMatrix();
	if( normal_model.get_rep() )
		normal_model.get_rep()->render_to_list( get_shaders(), hardware, render_list, model_ref );
#ifndef IPHONE_VERSION
	if( shadow_model.get_rep() )
		shadow_model.get_rep()->render_to_shadow_list( get_shaders(), hardware, render_list, model_ref );
#endif
	return Model::RenderToList( hardware, render_list );
}

void ModelFixed::ShadowSourceChanged(const filesystem::String& value)
{
#ifndef IPHONE_VERSION
	if( !shadow_model.get_rep() || shadow_model.get_rep_name() != value)
	{
		shadow_model.unload_rep();
		if( !value.empty() )
			shadow_model.load_rep(value);
	}
#endif
}

} // namespace node
} // namespace lib3d
} // namespace liba

